iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Mobile Development

關於 Flutter 開發的一些設計雜談系列 第 10

Day 10 - 暫存狀態 vs 程式狀態

  • 分享至 

  • xImage
  •  

當我們使用狀態管理之後,可能會思考,是否再也不需要使用 StatefulWidget 了?今天我們就來談談這個問題。首先,我們先看一個例子,假設今天畫設計師設計了一個按鈕,當按鈕被壓著時,按鈕需要變個顏色,讓使用者感知自己有按到按鈕

it_img_10_1.jpg
it_img_10_2.png
https://dartpad.dev/?id=1ce393e000000b9df586a11d7c6ae495

在上面的例子中,我們使用狀態管理來實現這個設計,可以發現在 ButtonStatus 中,我們維護了一個按鈕是否被按下的布林值,並且宣告了一個相對應的 Provider。雖然我們可以用狀態管理套件,完成這個功能,但實際上,會發現其實 ButtonStatus 並沒有多大的意義,形成一個壞味道:Lazy Class

把職責合併回 StatefulWidget

我們來看看使用 StatefulWidget 實現會變得如何?
it_img_10_3.png
https://dartpad.dev/?id=4c56071a63fa7416c4c22578694fa1e0

可以發現在這個場景中,使用 StatefulWidget 實現的話,我們只要在 State 維護一個布林值,並利用 setState 更新按鈕狀態與重 build 畫面。

暫存狀態 vs 程式狀態

客端程式中,大多時候都要維護各式各樣的狀態,我們可以把狀態分為兩種:暫存狀態和程式狀態。在按鈕的例子中,isPressed 的布林值就比較屬於暫存狀態,當 Button 消失時,這 isPressed 也隨之消失。在昨天顯示 User 的例子中,即便畫面關閉了,User 這個狀態還是需要存在程式中,以便其他畫面使用。

暫存狀態一定使用 StatefulWidget?

那是否暫存狀態就得永遠使用 StatefulWidget 呢?那倒也不是,管理狀態的邏輯比較複雜時,我們適當的使用狀態管理套件,將邏輯與畫面分開,能夠將一個比較複雜的類別,簡化成兩個比較簡單的類別,是具有意義的。在前天的選擇照片的例子中,選擇的照片在離開了選擇照片頁面之後,可能也不存在意義了。但是我們還是使用了狀態管理來改善,也是基於上述理由。

反之亦然,是否所有程式狀態也並非一定要使用狀態管理。在按鈕的例子中,假設需求變得複雜了,我們需要一個時間倒數的按鈕,並且擁有倒數/暫停等較複雜的行為時,使用狀態管理還是有一定好處。
it_img_10_4.png
https://dartpad.dev/?id=c93d29f9a38a0482a15ba028155d681e

結論

如何選擇使用 StatefulWidget 或者狀態管理套件,可以先判斷情境屬於暫存狀態或者程式狀態,並決定使用哪種實現,當實現一版之後,發現暫存狀態的邏輯過於複雜,還是可以改用狀態管理套件。

參考


上一篇
Day 9 - 跨頁面共享狀態
下一篇
Day 11 - 四處可見地倒數計時
系列文
關於 Flutter 開發的一些設計雜談30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言